package DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import modelo.Cliente;
import modelo.Localizacao;
import modelo.Time;
import connection.ConnectionManager;

/**
 * @author matheus_campos
 *
 */
public class ClienteDAOImp implements ClienteDAO{
	
	/**
	 * crie os metodos para alterar os clientes no banco de dados passando esses metodos abaixo
	 */
	 
	private final String INSERT = "INSERT INTO Cliente(id_time, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento,telefone) VALUES (?,?,?,?,?,?,?,?,?,?)";
	private final String UPDATE = "UPDATE Cliente SET id_time=?, id_localizacao=?, sobrenome=?, cpf=?, email=?, nome=?, senha=?, sexo=?, nascimento=?, telefone=? WHERE id_cliente = ?";
	private final String DELETE = "DELETE from Cliente WHERE id_cliente = ?";
	private final String ALL = "SELECT id_cliente, id_time, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento, telefone FROM Cliente";
	private final String LIKE = "SELECT id_cliente,id_time, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento, telefone FROM Cliente where nome like ?";
	private final String ID = "SELECT id_cliente, nome,id_time, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento,telefone FROM Cliente where id_cliente = ?";
	private final String CPF = "SELECT * FROM Cliente where cpf = ?";
	private final String EMAIL = "SELECT id_cliente, nome,id_time, id_localizacao, sobrenome, cpf, email, nome, senha, sexo, nascimento,telefone FROM Cliente where email = ?";
	private ConnectionManager connectionManager;
	private static Connection connection;
	
	ClienteDAOImp(){
		this.openConnection();
	}
	
	/** (non-Javadoc)
	 * @see DAO.DAO#isConnectionClose()
	 */
	public boolean isConnectionClose() {
		try {
			return connection.isClosed();
		} catch (SQLException ex) {
			return false;
		}
	}
	
	
	/** (non-Javadoc)
	 * @see DAO.DAO#salvar(java.lang.Object)
	 */
	@Override
	public Cliente salvar(Cliente e) {
		PreparedStatement ps = null;
		try {
			/**1 crie uma instancia de PreparedStatement 
			passe para ela a instrucao para realizar alteracoes em uma registro do banco*/
			
			ps = connection.prepareStatement(INSERT);
			
			ps.setObject(1, e.getTime().getIdTime());
			ps.setObject(2, e.getLocalizacao().getIdLocalizacao());
			ps.setObject(3, e.getSobrenome());
			ps.setObject(4, e.getCpf());
			ps.setObject(5, e.getEmail());
			ps.setObject(6, e.getNome());
			ps.setObject(7, e.getSenha());
			ps.setObject(8, e.isSexo());
			ps.setObject(9, e.getNascimento());
			ps.setObject(10, e.getTelefone());
			
			

			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return e;
		
	}
	
	@Override
	public void alterar(Cliente e) {
		PreparedStatement ps = null;
		
	
		try {
			/**2 crie uma instancia de PreparedStatement 
			*passe para ela a instrucao para realizar alteracoes em uma registro do banco
			*/ 
			ps = connection.prepareStatement(UPDATE);
			
			ps.setObject(1, e.getTime().getIdTime());
			ps.setObject(2, e.getLocalizacao().getIdLocalizacao());
			ps.setObject(3, e.getSobrenome());
			ps.setObject(4, e.getCpf());
			ps.setObject(5, e.getEmail());
			ps.setObject(6, e.getNome());
			ps.setObject(7, e.getSenha());
			ps.setObject(8, e.isSexo());
			ps.setObject(9, e.getNascimento());
			ps.setObject(10, e.getTelefone());
			ps.setObject(11, e.getId());
			

			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		
	}
	
	@Override
	public void deletar(Cliente e) {
		try {
			PreparedStatement ps = null;
			ps = connection.prepareStatement(DELETE);
			/**3 passe para o PreparedStatement o valor do id que deve ser excluido do banco de dados 
			 
			*/
			
			ps.setObject(1, e.getId());
			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		
	}
	
	@Override
	public List<Cliente> findAll() {
		List<Cliente> clientes = new ArrayList<Cliente>();
		LocalizacaoDAO local= DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		TimeDAO times =  DAOFactory.getTimeDAO();
		Time time = new Time();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(ALL);
			
			/**
			 * 4 Obtenha uma instancia de resultset
			 */
			rs = ps.executeQuery();
			
			while (rs.next()) {
				Cliente cliente = new Cliente();
				cliente.setId(rs.getInt("id_cliente"));
				time.setIdTime(rs.getInt("id_time"));
				cliente.setTime(times.buscaTimePorId(time).get(0));
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				cliente.setLocalizacao(locais.get(0));
				cliente.setSobrenome(rs.getString(4));
				cliente.setCpf(rs.getString(5));
				cliente.setEmail(rs.getString(6));
				cliente.setNome(rs.getString(7));
				cliente.setSenha(rs.getString(8));
				cliente.setSexo(rs.getBoolean(9));
				cliente.setNascimento(rs.getDate(10));
				cliente.setTelefone(rs.getString("telefone"));
				clientes.add(cliente);
				/**
				 * 5 crie uma instancia de cidade com os dados
				 *obtidos do banco e adicione a lista de cidadesf
				*/
			}

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return clientes;
	}
	
	@Override
	public void openConnection() {
		if ( connectionManager == null ) {
			connectionManager = ConnectionManager.getInstance();
		}
		
		if ( connection == null) {
			connection = connectionManager.getConnection();
		}
		
		if ( isConnectionClose() ) {
			connection = connectionManager.getConnection();
		}
		
	}
	
	@Override
	public void closeConnection() {
		if ( connection != null && connectionManager != null) {
			if ( ! this.isConnectionClose() ) {
				connectionManager.closeConnection(connection);
			}
		}
		
	}
	
	@Override
	public List<Cliente> buscaClientePorNome(Cliente cliente) {
		List<Cliente> clientes = new ArrayList<Cliente>();
		LocalizacaoDAO local=  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		TimeDAO times =  DAOFactory.getTimeDAO();
		Time time = new Time();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(LIKE);
			/**
			 * 6 informe o parmetro para instrucao like
			 */
			ps.setObject(1, cliente.getNome());
		
			rs = ps.executeQuery();

			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				time.setIdTime(rs.getInt("id_time"));
				time = times.buscaTimePorId(time).get(0);
				clientes.add(new Cliente(
						rs.getInt("id_cliente"),						
						time,
						rs.getString("nome"),
						rs.getString("sobrenome"),
						rs.getString("senha"),
						rs.getString("cpf"),
						rs.getBoolean("sexo"),
						rs.getDate("nascimento"),
						rs.getString("email"),
						locais.get(0),
						rs.getString("telefone")));
			}
		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return clientes;
	}
	
	@Override
	public List<Cliente> buscaClientePorId(Cliente cliente) {
		List<Cliente> clientes = new ArrayList<Cliente>();
		LocalizacaoDAO local=  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		TimeDAO times =  DAOFactory.getTimeDAO();
		Time time = new Time();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(ID);
			/**
			 * 6 informe o parmetro para instrucao ID 
			 */
			ps.setObject(1, cliente.getId());
		
			rs = ps.executeQuery();

			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				time.setIdTime(rs.getInt("id_time"));
				time = times.buscaTimePorId(time).get(0);
				clientes.add(new Cliente(
						rs.getInt("id_cliente"),						
						time,
						rs.getString("nome"),
						rs.getString("sobrenome"),
						rs.getString("senha"),
						rs.getString("cpf"),
						rs.getBoolean("sexo"),
						rs.getDate("nascimento"),
						rs.getString("email"),
						locais.get(0),
						rs.getString("telefone")));
			}
		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return clientes;
	}
	
	@Override
	
	public List<Cliente> buscaClientePorCpf(Cliente cliente) {
		List<Cliente> clientes = new ArrayList<Cliente>();
		LocalizacaoDAO local=  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		TimeDAO times =  DAOFactory.getTimeDAO();
		Time time = new Time();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(CPF);
			/**
			 * 7 informe o parmetro para instrucao like
			 */
			ps.setObject(1, cliente.getCpf());
		
			rs = ps.executeQuery();

			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				time.setIdTime(rs.getInt("id_time"));
				time = times.buscaTimePorId(time).get(0);
				clientes.add(new Cliente(
						rs.getInt("id_cliente"),						
						time,
						rs.getString("nome"),
						rs.getString("sobrenome"),
						rs.getString("senha"),
						rs.getString("cpf"),
						rs.getBoolean("sexo"),
						rs.getDate("nascimento"),
						rs.getString("email"),
						locais.get(0),
						rs.getString("telefone")));
			}
		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return clientes;
	}
	
	@Override
	public List<Cliente> buscaClientePorEmail(Cliente cliente) {
		List<Cliente> clientes = new ArrayList<Cliente>();
		LocalizacaoDAO local=  DAOFactory.getLocalizacaoDAO();
		List<Localizacao> locais = new ArrayList<Localizacao>();
		TimeDAO times =  DAOFactory.getTimeDAO();
		Time time = new Time();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(EMAIL);
			/**
			 * 8 informe o parmetro para instrucao like
			 */
			ps.setObject(1, cliente.getEmail());
		
			rs = ps.executeQuery();

			while (rs.next()) {
				locais = local.buscaLocalizacaoPorId(rs.getInt("id_localizacao"));
				time.setIdTime(rs.getInt("id_time"));
				time = times.buscaTimePorId(time).get(0);
				clientes.add(new Cliente(
						rs.getInt("id_cliente"),						
						time,
						rs.getString("nome"),
						rs.getString("sobrenome"),
						rs.getString("senha"),
						rs.getString("cpf"),
						rs.getBoolean("sexo"),
						rs.getDate("nascimento"),
						rs.getString("email"),
						locais.get(0),
						rs.getString("telefone")));
			}
		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return clientes;
	}
	
	
}
		
	
	

